//
//  ArchiveManager.m
//  ArchiveManager
//
//  Created by liangchenliang on 2021/1/26.
//  Copyright © 2017年 liangchenliang. All rights reserved.

#import "ArchiveManager.h"

typedef void (^ManagerStringBlock)(NSString *string);

@implementation ArchiveManager

/* 单例控制器 */
+ (instancetype)manager {
    return [[self alloc] init];
}

+ (instancetype)sharedInstance {
    return [[self alloc] init];
}

static ArchiveManager *instance = nil;
static dispatch_once_t onceToken;
- (instancetype)init {
    dispatch_once(&onceToken, ^{
        instance = [super init];
        
        _cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
        _documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
        _currentPath = _cachesPath;
        _enableCache = true;
        _fileManager = [NSFileManager defaultManager];
    });
    return instance;
}

#pragma mark - 从Url获取对应文件
- (void)startRequest:(NSString *)urlString key:(NSString *)password
{
    __weak __typeof(self)weakSelf = self;
    // 定义文件夹名称。压缩包名为文件夹名称
    NSString *folderName = [[urlString lastPathComponent] stringByDeletingPathExtension];
    // 文件夹路径
    NSString *folderPath = [_currentPath stringByAppendingPathComponent:folderName];

    
    if (self.enableCache == true) {
        if ([self directoryExists:folderPath]) {
            // 存在文件夹就删除
            // [_fileManager removeItemAtPath:folderPath error:nil];
            if (self.arrayBlock) {
                self.arrayBlock(true,folderPath,[self getAllFiles:folderPath],@"");
            }
            return;
        }
        
        // 不存在文件夹则下载、创建、解压
        [self downloadField:urlString block:^(NSString *filePath) {
            
            
            if (filePath) {
                NSString *resultPath = [_currentPath stringByAppendingPathComponent:folderName];
                if ([weakSelf createFolderWithPath:resultPath]) {
                    [weakSelf releaseZipFiles:filePath unzipPath:resultPath key:password];
                }else{
                    if (self.arrayBlock) {
                        self.arrayBlock(false,@"",@[],@"创建文件夹失败");
                    }
                }
            }else{
                if (self.arrayBlock) {
                    self.arrayBlock(false,@"",@[],@"下载文件失败");
                }
            }
            
        }];
        
    }
}

#pragma mark - 文件处理
#pragma mark 检测目录文件夹是否存在

- (NSArray *)getAllFiles:(NSString *)directoryPath{
    NSMutableArray *files = [NSMutableArray array];
    // 工程目录
    NSString *BASE_PATH = directoryPath;
    NSFileManager *myFileManager = [NSFileManager defaultManager];
    NSDirectoryEnumerator *myDirectoryEnumerator = [myFileManager enumeratorAtPath:BASE_PATH];
    
    BOOL isDir = NO;
    BOOL isExist = NO;
    
    //列举目录内容，可以遍历子目录
    for (NSString *path in myDirectoryEnumerator.allObjects) {
        NSLog(@"%@", path);  // 所有路径
        isExist = [myFileManager fileExistsAtPath:[NSString stringWithFormat:@"%@/%@", BASE_PATH, path] isDirectory:&isDir];
        if (isDir) {
            NSLog(@"%@", path);    // 目录路径
            [files addObject:path];
        } else {
            NSLog(@"%@", path);    // 文件路径
            [files addObject:path];
        }
    }
    return files;
}
/**
 检测目录文件夹是否存在
 
 @param directoryPath 目录路径
 @return 是否存在
 */
- (BOOL)directoryExists:(NSString *)directoryPath
{
//    BOOL isDir = NO;
//    BOOL isDirExist = [_fileManager fileExistsAtPath:directoryPath isDirectory:&isDir];
//    if (isDir && isDirExist) {
//        return YES;
//    }else{
//        return NO;
//    }
    BOOL isHave = [_fileManager fileExistsAtPath:directoryPath];
    NSLog(@"%@ 文件是否存在 - %zd",directoryPath,isHave?1:0);
    return isHave;
}

#pragma mark 获取文件夹下所有文件列表。
- (NSArray *)fileList:(NSString *)directoryPath
{
    return [[_fileManager contentsOfDirectoryAtPath:directoryPath error:nil] mutableCopy];
}

#pragma mark 下载文件。目录文件夹不存在，那么这步
- (void)downloadField:(NSString *)urlString block:(ManagerStringBlock)block
{
    // 创建会话管理者
    AFHTTPSessionManager *manager =[AFHTTPSessionManager manager];
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 下载文件
    [[manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        if (self.downloadProgressBlock){
            self.downloadProgressBlock(downloadProgress.fractionCompleted*100);
        }
        
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        NSString *fullPath = [_currentPath stringByAppendingPathComponent:response.suggestedFilename];
        
        // 返回一个URL, 返回的这个URL就是文件的位置的完整路径
        return [NSURL fileURLWithPath:fullPath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        if (self.downloadProgressBlock){
            self.downloadProgressBlock(100);
        }
        if (block) {
            block([filePath path]);
        }
    }] resume];
}


#pragma mark 创建文件夹。下载完文件，文件需要解压到这个文件夹
- (BOOL)createFolderWithPath:(NSString *)folderPath
{
    // 在路径下创建文件夹
    return [_fileManager createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}

#pragma mark - SSZipArchive
#pragma mark 解压
- (void)releaseZipFiles:(NSString *)zipPath unzipPath:(NSString *)unzipPath key:(NSString *)password{
    if (password.length == 0) {
        if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath delegate:self]) {
            
        }else {
            // NSLog(@"解压失败");
            NSLog(@"ArchiveManager -解压Archive失败");
            if (self.arrayBlock) {
                self.arrayBlock(false,@"",@[],@"Archive失败");
            }
        }
    }else{
        if ([SSZipArchive unzipFileAtPath:zipPath toDestination:unzipPath overwrite:true password:password error:nil delegate:self]) {
            
        }else {
            // NSLog(@"解压失败");
            NSLog(@"ArchiveManager -解压失败");
            if (self.arrayBlock) {
                self.arrayBlock(false,@"",@[],@"Archive失败");
            }
        }
    }
}

#pragma mark SSZipArchiveDelegate
- (void)zipArchiveDidUnzipArchiveAtPath:(NSString *)path zipInfo:(unz_global_info)zipInfo unzippedPath:(NSString *)unzippedPath
{
    // 解压会出现多余的文件夹__MACOSX，删除掉吧
    NSString *invalidFolder = [unzippedPath stringByAppendingPathComponent:@"__MACOSX"];
    [_fileManager removeItemAtPath:invalidFolder error:nil];
    /*
    // 或者过滤数组，只取所需要的png文件名
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF ENDSWITH %@", @".png"];
    NSArray *reslutFilteredArray = [fileList filteredArrayUsingPredicate:predicate];
    */
    NSArray *fileList = [self fileList:unzippedPath];
    if (self.arrayBlock) {
        self.arrayBlock(true,unzippedPath, fileList,@"");
    }
}

- (BOOL)createZipFile:(NSString *)zipPath contentPath:(NSString *)filePath withPassword:(NSString *)password{
    if ([self directoryExists:zipPath]) {
        // 存在文件夹就删除
        [_fileManager removeItemAtPath:zipPath error:nil];
    }
    NSString *fullPath = [_currentPath stringByAppendingPathComponent:zipPath];
    return [SSZipArchive createZipFileAtPath:fullPath withContentsOfDirectory:filePath withPassword:password];
}

- (void)deletedPath:(NSString *)folderPath{
    [[NSFileManager defaultManager] removeItemAtPath:folderPath error:nil];
}

- (void)deletedCurrentPath{
    NSString *folderPath = [[ArchiveManager manager] currentPath];
    [self deletedPath:folderPath];
}

- (ArchiveManager *)documentsPath{
    _currentPath = _documentsPath;
    return self;
}

- (ArchiveManager *)cachesPath{
    _currentPath = _cachesPath;
    return self;
}
@end
